#!/bin/bash


version="0.8.8"

if ! $(elm -v 2> /dev/null | grep 0.18 > /dev/null ); then
    echo "Elchemy requires elm 0.18. Install it and make sure it's available system-wide."
    echo "For 0.19 support visit https://github.com/wende/elchemy/issues/348"
    exit 1
fi

set -e

VERBOSE=false
if [[ $* == *--verbose* ]]; then
  VERBOSE=true
fi

function create_file {
    local file=$1
    if [[ ${file} == *"elm-stuff/packages"* ]]; then
        file=${file/elm-stuff\/packages/elm-deps}
    fi
    mkdir -p `dirname $file`
    echo "" > $file
    echo "$file"
}

SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
    DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
    SOURCE="$(readlink "$SOURCE")"
    [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
SOURCE_DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"

case "$1" in
    version)
        echo "Elchemy $version"
        ;;
    clean)
      rm -rf ./elm-deps
      rm -rf ./elm-stuff
      rm -rf ~/.elm-install/github.com/
      find . | grep "\.elchemy.ex" | xargs rm -f
      rm -rf .elchemy
      ;;
    new)
        mix new $2
        cd $2
        $SOURCE_DIR/elchemy init
        ;;
    init)
        if [ -a ./mix.exs ]
        then
            cp $SOURCE_DIR/templates/elchemy.exs ./.elchemy.exs
            mix archive.install "https://github.com/wende/elchemy/releases/download/$version/elchemy-$version.ez"
            mkdir -p elm
            cp $SOURCE_DIR/templates/elm-package.json ./
            cp $SOURCE_DIR/templates/Hello.elm ./elm/
            if [ -d ./test ]; then
                cp $SOURCE_DIR/templates/elchemy_test.exs ./test/
            fi
            printf  "Elchemy $version initialised. Make sure to add:\n\n\t|> elem(Code.eval_file(\".elchemy.exs\"), 0).init\n\nto your mix.exs file as the last line of the project() function.\nThis pipes the project keyword list to the elchemy init function to configure some additional values.\n\nThen run mix test to check if everything went fine\n"
            printf "\nelm-deps" >> .gitignore
            printf "\nelm-stuff" >> .gitignore
            printf "\node_modules" >> .gitignore
            printf "\.elchemy" >> .gitignore
        else
            printf  "ERROR: No elixir project found. Make sure to run init in a project"
        fi
    ;;
    compile)
        # Create ./.elchemy if doesn't exist
        mkdir -p ".elchemy"
        MTIME="$(cat ".elchemy/mtime" 2> /dev/null || echo "1995-04-10 23:35:02")"
        echo "" > .elchemy/output
        if [ ! -d ./elm-deps ] || [[ !  $(find ./elm-package.json -newermt "$MTIME") == "" ]]; then
            if ! hash elm-github-install 2>/dev/null; then
                echo "No elm-github-install found. Installing..."
                npm i -g elm-github-install@1.6.1
            fi
            echo "-- Downloading Elchemy deps --"
            elm-install
        fi
        # Copy all elixir files that are inside packages
        echo "-- Copying Elixir native files --"
        for f in `{ find -L elm-stuff/packages -name "*.ex*" | grep -v "\.elchemy\.ex" ;}`
        do
          if [ $VERBOSE = true ]; then
            echo "FOUND $f"
          fi
          file="${file/^elm\//lib\//}"
          file=$(create_file $f)
          if [ $VERBOSE = true ]; then
             echo "TO $file"
           fi
          cp $f $file
        done
        i=0
        echo "-- Compiling Elm files --"
        # Find all elm files inside packages and compile them
        for f in `{ find $2 -name "*.elm" -newermt "$MTIME" | grep -v "elm-stuff" | grep -v "#." ; find -L elm-stuff/packages -name "*.elm" -newermt "$MTIME" | grep -v "/tests/" | grep -v "/example/" ;}`
        do
            if [[ ${f} == *"elm-lang"* ]] || [[ ${f} == *"Elchemy.elm"* ]]; then
                continue
            fi
            echo "----------"
            echo "Type Checking $f"
            echo ">>>>$f" >> .elchemy/output
            # We don't need to typecheck deps again
            if [[ ${f} != *"elm-stuff"* ]] && ! [[ $* == *--unsafe* ]]; then
                (echo n | elm-make $f --output .elchemy/output_tmp.js) || { echo 'Type Check failed' ; exit 1; }
                rm .elchemy/output_tmp.js
            fi
            i=$((i+1))
            echo "#$i"
            cat $f >> .elchemy/output
        done
        echo "-- Linking files --"
        node --max_old_space_size=8192 $SOURCE_DIR/elchemy.js .elchemy/output .elchemy/elixir_output .elchemy/cache.json
        current_file=""
        while IFS= read -r line; do
            if [[ $line =~ ">>>>" ]]; then
                current_file="${line/\/\///}"
                current_file="${current_file/>>>>/}"
                echo "Linking: $current_file"
                current_file="${current_file/$2\//$3/}"
                current_file="${current_file%%.elm}.elchemy.ex"
                current_file=$(echo ${current_file} | perl -pe 's/([a-z0-9])([A-Z])/$1_\L$2/g')
                current_file=$(create_file $current_file)
                echo "To: $current_file"
                else
                if [ "$current_file" != "" ]; then
                    printf '%s\n' "$line" >> "$current_file"
                fi
            fi
        done < .elchemy/elixir_output
        #rm .elchemy/elixir_output
        #rm .elchemy/output
        echo $(date +"%Y-%m-%d %H:%M:%S") > .elchemy/mtime
        ;;
    *)
        echo $"Usage: $0 <COMMAND> [<ARGS>]"
        cat <<EOF

Available commands include:

    new <PROJECT_NAME>
        Start a new project

    init
        Add Elchemy to an existing project

    compile [INPUT_DIR] [OUTPUT_DIR] [--unsafe]
        Compile Elchemy source code

    clean
        Remove temporary files

    version
        Print Elchmey's version number number and exit

EOF
        exit 1

esac
